package com.wiz.weixin.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.wiz.weixin.common.RedisConstant;
import com.wiz.weixin.manager.HttpManager;
import com.wiz.weixin.manager.RedisManager;
import com.wiz.weixin.manager.WxUserManager;
import com.wiz.weixin.mapper.StationMapper;
import com.wiz.weixin.service.StationService;
import com.wiz.weixin.tencent.vo.UserInfoVo;
import com.wiz.weixin.to.BossWeixinConfigTO;
import com.wiz.weixin.to.ChargeTotalTO;
import com.wiz.weixin.to.FuellingTotalTO;
import com.wiz.weixin.to.OilTankTO;
import com.wiz.weixin.to.PrPriceTO;
import com.wiz.weixin.to.StationTO;
import com.wiz.weixin.type.JusType;
import com.wiz.weixin.util.DateUtil;

@Service("stationService")
public class StationServiceImpl implements StationService,RedisConstant {
	private transient final Logger log = LoggerFactory.getLogger(getClass());
	
	private DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

	@Resource
	private Gson gson;
	@Resource	
	private StationMapper stationMapper;
	@Resource
	private HttpManager httpManager;
	@Resource
	private RedisManager redisManager;
	@Resource
	private WxUserManager wxUserManager;
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getFpPriceListByStation(String openId,Model model) throws Exception{
		Object o = redisManager.get(String.format(FP_PR_PRICE_BY_OPEN_ID, openId));
		if(o == null){
			String paramsStr = getBossWeixinStr(openId,JusType.FP_PRICE.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<PrPriceTO>> map = new HashMap<String, List<PrPriceTO>>();
			if(StringUtils.isBlank(paramsStr)){
				redisManager.set(String.format(FP_PR_PRICE_BY_OPEN_ID, openId), gson.toJson(map),3600*2);
				model.addAttribute("map", map);
				return null;
			}
			List<PrPriceTO> prPriceList = null;
			List<PrPriceTO> result = stationMapper.getFpPriceListByStation(paramsStr);
			for (PrPriceTO prPriceTO : result) {
				String key = prPriceTO.getStationId()+":"+prPriceTO.getStationName();
				if(map.containsKey(key)){
					prPriceList = map.get(key);
				}else{
					prPriceList = new ArrayList<PrPriceTO>();
				}
				prPriceList.add(prPriceTO);
				map.put(key, prPriceList);
			}
			redisManager.set(String.format(FP_PR_PRICE_BY_OPEN_ID, openId), gson.toJson(map),3600*2);
			model.addAttribute("map", map);
		}else{
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<PrPriceTO>>>(){}.getType());
			model.addAttribute("map", map);
		}
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getChargeTotalByStation(String openId,Model model) throws Exception{
		Object o = redisManager.get(String.format(CHARGE_TOTAL_BY_OPEN_ID, openId));
		if(o == null){
			String dd = DateUtil.formatDateTime(new Date());
			String paramsStr = getBossWeixinStr(openId,JusType.TODAY_CHARGE.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<ChargeTotalTO>> map = new HashMap<String, List<ChargeTotalTO>>();
			if(StringUtils.isBlank(paramsStr)){
				redisManager.set(String.format(CHARGE_TOTAL_BY_OPEN_ID, openId), gson.toJson(map),900);
				redisManager.set(String.format(CHARGE_DATE_BY_OPEN_ID, openId), dd,900);
				model.addAttribute("udate", dd);
				model.addAttribute("map", map);
				return null;
			}
			List<ChargeTotalTO> chargeTotalList = null;
			List<ChargeTotalTO> result = stationMapper.getChargeTotalByStation(paramsStr);
			for(ChargeTotalTO chargeTO : result) {
				String key = chargeTO.getStationId()+":"+chargeTO.getStationName();
				if(map.containsKey(key)){
					chargeTotalList = map.get(key);
				}else{
					chargeTotalList = new ArrayList<ChargeTotalTO>();
					if(chargeTO.getPaidTypeId() != -1){
						chargeTotalList.add(stationMapper.getChargeSumByStation(chargeTO.getStationId()));
					}
				}
				chargeTotalList.add(chargeTO);
				map.put(key, chargeTotalList);
			}
			redisManager.set(String.format(CHARGE_TOTAL_BY_OPEN_ID, openId), gson.toJson(map),900);
			redisManager.set(String.format(CHARGE_DATE_BY_OPEN_ID, openId), dd,900);
			model.addAttribute("udate", dd);
			model.addAttribute("map", map);
		}else{
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<ChargeTotalTO>>>(){}.getType());
			model.addAttribute("map", map);
			model.addAttribute("udate", redisManager.get(String.format(CHARGE_DATE_BY_OPEN_ID, openId)).toString());
		}
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getFuellingTotalByStationInToday(String openId, Model model) throws Exception {
		Object o = redisManager.get(String.format(FUELLING_TODAY_TOTAL_BY_OPEN_ID, openId));
		if(o == null){
			String dd = DateUtil.formatDateTime(new Date());
			String paramsStr = getBossWeixinStr(openId,JusType.TODAY_FUELLING.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<FuellingTotalTO>> map = new HashMap<String, List<FuellingTotalTO>>();
			if(StringUtils.isBlank(paramsStr)){
				redisManager.set(String.format(FUELLING_TODAY_TOTAL_BY_OPEN_ID, openId), gson.toJson(map),900);
				redisManager.set(String.format(FUELLING_TODAY_DATE_BY_OPEN_ID, openId), dd,900);
				model.addAttribute("map", map);
				model.addAttribute("udate", dd);
				return null;
			}
			List<FuellingTotalTO> fuellingTotalList = null;
			List<FuellingTotalTO> result = stationMapper.getFuellingTotalByStation(paramsStr,1);
			for(FuellingTotalTO fuellingTO : result) {
				String key = fuellingTO.getStationId()+":"+fuellingTO.getStationName();
				if(map.containsKey(key)){
					fuellingTotalList = map.get(key);
				}else{
					fuellingTotalList = new ArrayList<FuellingTotalTO>();
					if(fuellingTO.getPrId() != -1){
						fuellingTotalList.add(stationMapper.getFuellingSumByStation(fuellingTO.getStationId(),1));
					}
				}
				fuellingTotalList.add(fuellingTO);
				map.put(key, fuellingTotalList);
			}
			redisManager.set(String.format(FUELLING_TODAY_TOTAL_BY_OPEN_ID, openId), gson.toJson(map),900);
			redisManager.set(String.format(FUELLING_TODAY_DATE_BY_OPEN_ID, openId), dd,900);
			model.addAttribute("map", map);
			model.addAttribute("udate", dd);
		}else{
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<FuellingTotalTO>>>(){}.getType());
			model.addAttribute("map", map);
			model.addAttribute("udate", redisManager.get(String.format(FUELLING_TODAY_DATE_BY_OPEN_ID, openId)).toString());
		}
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getOilTankListByStation(String openId, Model model) throws Exception {
		Object o = redisManager.get(String.format(OIL_TANK_BY_OPEN_ID, openId));
		if(o == null){
			String paramsStr = getBossWeixinStr(openId,JusType.TANKER.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<OilTankTO>> map = new HashMap<String, List<OilTankTO>>();
			if(StringUtils.isBlank(paramsStr)){
				String dd = DateUtil.formatDateTime(new Date());
				redisManager.set(String.format(OIL_TANK_DATE_BY_OPEN_ID, openId), dd,900);
				redisManager.set(String.format(OIL_TANK_BY_OPEN_ID, openId), gson.toJson(map),900);
				model.addAttribute("map", map);
				return null;
			}
			List<OilTankTO> oilTankList = null;
			List<OilTankTO> result = stationMapper.getOilTankListByStation(paramsStr);
			String date = null;
			for (OilTankTO oilTankTO : result) {
				String key = oilTankTO.getStationId()+":"+oilTankTO.getStationName();
				if(map.containsKey(key)){
					oilTankList = map.get(key);
				}else{
					oilTankList = new ArrayList<OilTankTO>();
				}
				if(date == null){
					date = oilTankTO.getCreatedTime();
				}else{
					if(compare_date(date,oilTankTO.getCreatedTime()) == -1){
						date = oilTankTO.getCreatedTime();
					}
				}
				oilTankList.add(oilTankTO);
				map.put(key, oilTankList);
			}
			redisManager.set(String.format(OIL_TANK_DATE_BY_OPEN_ID, openId), date,900);
			redisManager.set(String.format(OIL_TANK_BY_OPEN_ID, openId), gson.toJson(map),900);
			model.addAttribute("map", map);
			model.addAttribute("udate", date);
		}else{
			String dd = DateUtil.formatDateTime(new Date());
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<OilTankTO>>>(){}.getType());
			model.addAttribute("map", map);
			model.addAttribute("udate", dd);
		}
		return null;
	}

	/**
	 * 获取openid对应管理油站列表
	 * @param openId
	 * @param jusType 权限ID
	 * @return
	 */
	private String getBossWeixinStr(String openId, int jusType){
		List<BossWeixinConfigTO> configList = stationMapper.getBossConfig(openId);
		if(configList.size()<1){//认为未绑定
			return "/error";
		}
		List<StationTO> stationList;
		StringBuffer paramsStr = new StringBuffer();
		for(BossWeixinConfigTO config:configList){
			if((config.getJusType() & jusType) != jusType){
				continue;
			}
			if(config.getIsAllStaion() == 1){
				stationList = stationMapper.getStationsByHqId(config.getHqId());
				for(StationTO stationTO:stationList){
					paramsStr.append(stationTO.getStationId()).append(",");
				}
			}else{
				paramsStr.append(config.getManagedStation());
			}
		}
		if(paramsStr.toString().endsWith(",")){
			paramsStr.deleteCharAt(paramsStr.length()-1);
		}
		return paramsStr.toString();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getFuellingTotalByStationInYestoday(String openId, Model model) throws Exception {
		Object o = redisManager.get(String.format(FUELLING_YESTODAY_TOTAL_BY_OPEN_ID, openId));
		if(o == null){
			String dd = DateUtil.formatDate(System.currentTimeMillis()-1000*3600*24);
			String paramsStr = getBossWeixinStr(openId,JusType.YESDAY_FUELLING.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<FuellingTotalTO>> map = new HashMap<String, List<FuellingTotalTO>>();
			if(StringUtils.isBlank(paramsStr)){
				redisManager.set(String.format(FUELLING_YESTODAY_TOTAL_BY_OPEN_ID, openId), gson.toJson(map),3600*12);
				redisManager.set(String.format(FUELLING_YESTODAY_DATE_BY_OPEN_ID, openId), dd,3600*12);
				model.addAttribute("map", map);
				model.addAttribute("udate", dd);
				return null;
			}
			List<FuellingTotalTO> fuellingTotalList = null;
			List<FuellingTotalTO> result = stationMapper.getFuellingTotalByStation(paramsStr,0);
			for(FuellingTotalTO fuellingTO : result) {
				String key = fuellingTO.getStationId()+":"+fuellingTO.getStationName();
				if(map.containsKey(key)){
					fuellingTotalList = map.get(key);
				}else{
					fuellingTotalList = new ArrayList<FuellingTotalTO>();
					if(fuellingTO.getPrId() != -1){
						fuellingTotalList.add(stationMapper.getFuellingSumByStation(fuellingTO.getStationId(),0));
					}
				}
				fuellingTotalList.add(fuellingTO);
				map.put(key, fuellingTotalList);
			}
			redisManager.set(String.format(FUELLING_YESTODAY_TOTAL_BY_OPEN_ID, openId), gson.toJson(map),3600*12);
			redisManager.set(String.format(FUELLING_YESTODAY_DATE_BY_OPEN_ID, openId), dd,3600*12);
			model.addAttribute("map", map);
			model.addAttribute("udate", dd);
		}else{
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<FuellingTotalTO>>>(){}.getType());
			model.addAttribute("map", map);
			model.addAttribute("udate", redisManager.get(String.format(FUELLING_YESTODAY_DATE_BY_OPEN_ID, openId)).toString());
		}
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getFuellingByThisGroup(String openId, Model model) throws Exception {
		Object o = redisManager.get(String.format(FUELLING_THIS_GROUP_BY_OPEN_ID, openId));
		if(o == null){
			String dd = DateUtil.formatDateTime(new Date());
			String paramsStr = getBossWeixinStr(openId,JusType.GROUP_FUELLING.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<FuellingTotalTO>> map = new HashMap<String, List<FuellingTotalTO>>();
			if(StringUtils.isBlank(paramsStr)){
				redisManager.set(String.format(FUELLING_THIS_GROUP_BY_OPEN_ID, openId), gson.toJson(map),900);
				redisManager.set(String.format(FUELLING_THIS_GROUP_DATE_BY_OPEN_ID, openId), dd,900);
				model.addAttribute("map", map);
				model.addAttribute("udate", dd);
				return null;
			}
			List<FuellingTotalTO> fuellingTotalList = null;
			List<FuellingTotalTO> result = stationMapper.getFuellingByGroup(paramsStr,0);
			for(FuellingTotalTO fuellingTO : result) {
				String key = fuellingTO.getStationId()+":"+fuellingTO.getStationName()+"("+fuellingTO.getGroupNo()+")";
				if(map.containsKey(key)){
					fuellingTotalList = map.get(key);
				}else{
					fuellingTotalList = new ArrayList<FuellingTotalTO>();
					if(fuellingTO.getPrId() != -1){
						fuellingTotalList.add(stationMapper.getFuellingSumByGroup(fuellingTO.getGroupNo()));
					}
				}
				fuellingTotalList.add(fuellingTO);
				map.put(key, fuellingTotalList);
			}
			redisManager.set(String.format(FUELLING_THIS_GROUP_BY_OPEN_ID, openId), gson.toJson(map),900);
			redisManager.set(String.format(FUELLING_THIS_GROUP_DATE_BY_OPEN_ID, openId), dd,900);
			model.addAttribute("map", map);
			model.addAttribute("udate", dd);
		}else{
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<FuellingTotalTO>>>(){}.getType());
			model.addAttribute("map", map);
			model.addAttribute("udate", redisManager.get(String.format(FUELLING_THIS_GROUP_DATE_BY_OPEN_ID, openId)).toString());
		}
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public String getFuellingByLastGroup(String openId, Model model) throws Exception {
		Object o = redisManager.get(String.format(FUELLING_LAST_GROUP_BY_OPEN_ID, openId));
		if(o == null){
			String dd = DateUtil.formatDateTime(new Date());
			String paramsStr = getBossWeixinStr(openId,JusType.LAST_GROUP_FUELLING.getId());
			if(paramsStr.equals("/error")){
				model.addAttribute("msg", "请在云平台申请绑定");
				return paramsStr;
			}
			Map<String,List<FuellingTotalTO>> map = new HashMap<String, List<FuellingTotalTO>>();
			if(StringUtils.isBlank(paramsStr)){
				redisManager.set(String.format(FUELLING_LAST_GROUP_BY_OPEN_ID, openId), gson.toJson(map),1800);
				redisManager.set(String.format(FUELLING_LAST_GROUP_DATE_BY_OPEN_ID, openId), dd,1800);
				model.addAttribute("map", map);
				model.addAttribute("udate", dd);
				return null;
			}
			List<FuellingTotalTO> fuellingTotalList = null;
			List<FuellingTotalTO> result = stationMapper.getFuellingByGroup(paramsStr,1);
			for(FuellingTotalTO fuellingTO : result) {
				String key = fuellingTO.getStationId()+":"+fuellingTO.getStationName()+"("+fuellingTO.getGroupNo()+")";
				if(map.containsKey(key)){
					fuellingTotalList = map.get(key);
				}else{
					fuellingTotalList = new ArrayList<FuellingTotalTO>();
					if(fuellingTO.getPrId() != -1){
						fuellingTotalList.add(stationMapper.getFuellingSumByGroup(fuellingTO.getGroupNo()));
					}
				}
				fuellingTotalList.add(fuellingTO);
				map.put(key, fuellingTotalList);
			}
			redisManager.set(String.format(FUELLING_LAST_GROUP_BY_OPEN_ID, openId), gson.toJson(map),1800);
			redisManager.set(String.format(FUELLING_LAST_GROUP_DATE_BY_OPEN_ID, openId), dd,1800);
			model.addAttribute("map", map);
			model.addAttribute("udate", dd);
		}else{
			Map<String,List<PrPriceTO>> map = gson.fromJson(o.toString(), new TypeToken<Map<String,List<FuellingTotalTO>>>(){}.getType());
			model.addAttribute("map", map);
			model.addAttribute("udate", redisManager.get(String.format(FUELLING_LAST_GROUP_DATE_BY_OPEN_ID, openId)).toString());
		}
		return null;
	}

	@Override
	public boolean bindBossWeixin(String openId,String content) throws Exception {
		UserInfoVo user = wxUserManager.getUserInfo(openId);
		int result = 0;
		String code = content.substring(4);
		if(user == null){
			result = stationMapper.updateBindBossWx(openId, code,null, null);
		}else{
			result = stationMapper.updateBindBossWx(openId, code, user.getHeadimgurl(), user.getNickname());
		}
		if(result>0){
			return true;
		}
		return false;
	}
	
	 private int compare_date(String date1, String date2) {
        try {
            Date dt1 = df.parse(date1);
            Date dt2 = df.parse(date2);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }
}
